package com.java.test1;

import org.junit.Test;

/**
 * String的使用
 *
 * @author luzhikun
 * @date 2020/12/26-11:23
 */
public class StringTest_1 {
    /**
     * String：字符串：用一对“”引起来表示
     * 1.String声明为final的，不可被继承
     * 2.String实现了Serializable接口：可序列化的  表示字符串是支持可序列化的
     * 实现了Comparable接口：可比较的    表示String是可以比较大小的
     * 3.String在内部定义了final char[] value 用于存储字符串数据
     * 4.String：代表不可变的字符序列， 简称：不可变性
     * 体现：1.当对字符串重新赋值时，需要重新指定内存区域赋值，不能在原有的value上进行赋值.
     * 2.在对现有的字符串进行连接操作时，也需要重新制定区域赋值，不能在原有的value上赋值。
     * 3.当调用String中的replace（）方法修改指定字符或者字符串的时候，也需要重新指定区域赋值，
     * 不能在原有的value上赋值。
     * 5.通过字面量的方式（区别于new）给一个字符串赋值，此时的字符串声明在字符串常量池中
     * 6.字符串常量池是不会存储相同内容的字符串的
     * <p>
     * <p>
     * 面试题一：
     * String 的实例化方式：
     * 实例化方式一：通过字面量定义的方式
     * 实例化方式二：通过new+构造器的方式
     * 面试题二：
     * String s=new String("abc");方式创建对象，在内存中创建了几个对象？
     * 两个：一个是堆空间中new的结构，一个是char[]对应的字符串常量池中真实数值。
     */
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        s1 = "hello";
        s1 = "def";


        System.out.println(s1 == s2);     //true      比较s1和s2的地址值
        System.out.println(s1);         //"abc"     //"hello"
        System.out.println(s2);         //"abc"

//        System.out.println(s1);         //hello


        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);         //defabc
        System.out.println(s2);         //abc

        //总结： 字符串常量池中当内容相同时，他肯定会是共用这个地址，当内容不同或发生改变时，就会新造一个对象在常量池中

        String s4 = "abc";
        String s5 = s4.replace('a', 'c');
        System.out.println(s4);
        System.out.println(s5);


        //通过字面量的方式定义：此时的变量都在字符串常量池中
        String s6 = "javaEE";
        String s7 = "javaEE";

        //通过new+构造器的方式定义:此时的变量都在堆空间中
        String s8 = new String("javaEE");
        String s9 = new String("javaEE");

        System.out.println(s6 == s7);     //true
        System.out.println(s6 == s8);     //false
        System.out.println(s6 == s9);     //false
        System.out.println(s8 == s9);     //false


        Person p1 = new Person("tom", 14);
        Person p2 = new Person("tom", 14);


        System.out.println(p1.name == p2.name);           //true
        System.out.println(p1.name.equals(p2.name));    //true


    }

    /**
     * 结论：
     * 1.字符串与字符串的拼接结果在常量池中，且常量池中不会出现相同内容的常量。
     * 2.只要其中一个是变量，就存在堆空间中
     * 3.如果拼接的结果调用intern（）方法，返回值就在常量池中。
     */
    @Test
    public void test1() {
        String s1 = "javaEE";
        String s2 = "handop";

        String s3 = "javaEEhandop";
        String s4 = "javaEE" + "handop";

        String s5 = s1 + "handop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s5 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s7);//false

        String s8 = s5.intern();  //String 类中的方法
        System.out.println(s3 == s8); //true
    }
}
